home *** CD-ROM | disk | FTP | other *** search
/ Freelog 100 / FreelogNo100-NovembreDecembre2010.iso / Musique / solfege / solfege-win32-3.17.0.exe / {app} / bin / Lib / bsddb / test / test_associate.py < prev    next >
Text File  |  2006-03-13  |  16KB  |  479 lines

  1. """
  2. TestCases for DB.associate.
  3. """
  4.  
  5. import sys, os, string
  6. import tempfile
  7. import time
  8. from pprint import pprint
  9.  
  10. try:
  11.     from threading import Thread, currentThread
  12.     have_threads = 1
  13. except ImportError:
  14.     have_threads = 0
  15.  
  16. import unittest
  17. from test_all import verbose
  18.  
  19. try:
  20.     # For Pythons w/distutils pybsddb
  21.     from bsddb3 import db, dbshelve
  22. except ImportError:
  23.     # For Python 2.3
  24.     from bsddb import db, dbshelve
  25.  
  26.  
  27. #----------------------------------------------------------------------
  28.  
  29.  
  30. musicdata = {
  31. 1 : ("Bad English", "The Price Of Love", "Rock"),
  32. 2 : ("DNA featuring Suzanne Vega", "Tom's Diner", "Rock"),
  33. 3 : ("George Michael", "Praying For Time", "Rock"),
  34. 4 : ("Gloria Estefan", "Here We Are", "Rock"),
  35. 5 : ("Linda Ronstadt", "Don't Know Much", "Rock"),
  36. 6 : ("Michael Bolton", "How Am I Supposed To Live Without You", "Blues"),
  37. 7 : ("Paul Young", "Oh Girl", "Rock"),
  38. 8 : ("Paula Abdul", "Opposites Attract", "Rock"),
  39. 9 : ("Richard Marx", "Should've Known Better", "Rock"),
  40. 10: ("Rod Stewart", "Forever Young", "Rock"),
  41. 11: ("Roxette", "Dangerous", "Rock"),
  42. 12: ("Sheena Easton", "The Lover In Me", "Rock"),
  43. 13: ("Sinead O'Connor", "Nothing Compares 2 U", "Rock"),
  44. 14: ("Stevie B.", "Because I Love You", "Rock"),
  45. 15: ("Taylor Dayne", "Love Will Lead You Back", "Rock"),
  46. 16: ("The Bangles", "Eternal Flame", "Rock"),
  47. 17: ("Wilson Phillips", "Release Me", "Rock"),
  48. 18: ("Billy Joel", "Blonde Over Blue", "Rock"),
  49. 19: ("Billy Joel", "Famous Last Words", "Rock"),
  50. 20: ("Billy Joel", "Lullabye (Goodnight, My Angel)", "Rock"),
  51. 21: ("Billy Joel", "The River Of Dreams", "Rock"),
  52. 22: ("Billy Joel", "Two Thousand Years", "Rock"),
  53. 23: ("Janet Jackson", "Alright", "Rock"),
  54. 24: ("Janet Jackson", "Black Cat", "Rock"),
  55. 25: ("Janet Jackson", "Come Back To Me", "Rock"),
  56. 26: ("Janet Jackson", "Escapade", "Rock"),
  57. 27: ("Janet Jackson", "Love Will Never Do (Without You)", "Rock"),
  58. 28: ("Janet Jackson", "Miss You Much", "Rock"),
  59. 29: ("Janet Jackson", "Rhythm Nation", "Rock"),
  60. 30: ("Janet Jackson", "State Of The World", "Rock"),
  61. 31: ("Janet Jackson", "The Knowledge", "Rock"),
  62. 32: ("Spyro Gyra", "End of Romanticism", "Jazz"),
  63. 33: ("Spyro Gyra", "Heliopolis", "Jazz"),
  64. 34: ("Spyro Gyra", "Jubilee", "Jazz"),
  65. 35: ("Spyro Gyra", "Little Linda", "Jazz"),
  66. 36: ("Spyro Gyra", "Morning Dance", "Jazz"),
  67. 37: ("Spyro Gyra", "Song for Lorraine", "Jazz"),
  68. 38: ("Yes", "Owner Of A Lonely Heart", "Rock"),
  69. 39: ("Yes", "Rhythm Of Love", "Rock"),
  70. 40: ("Cusco", "Dream Catcher", "New Age"),
  71. 41: ("Cusco", "Geronimos Laughter", "New Age"),
  72. 42: ("Cusco", "Ghost Dance", "New Age"),
  73. 43: ("Blue Man Group", "Drumbone", "New Age"),
  74. 44: ("Blue Man Group", "Endless Column", "New Age"),
  75. 45: ("Blue Man Group", "Klein Mandelbrot", "New Age"),
  76. 46: ("Kenny G", "Silhouette", "Jazz"),
  77. 47: ("Sade", "Smooth Operator", "Jazz"),
  78. 48: ("David Arkenstone", "Papillon (On The Wings Of The Butterfly)",
  79.      "New Age"),
  80. 49: ("David Arkenstone", "Stepping Stars", "New Age"),
  81. 50: ("David Arkenstone", "Carnation Lily Lily Rose", "New Age"),
  82. 51: ("David Lanz", "Behind The Waterfall", "New Age"),
  83. 52: ("David Lanz", "Cristofori's Dream", "New Age"),
  84. 53: ("David Lanz", "Heartsounds", "New Age"),
  85. 54: ("David Lanz", "Leaves on the Seine", "New Age"),
  86. 99: ("unknown artist", "Unnamed song", "Unknown"),
  87. }
  88.  
  89. #----------------------------------------------------------------------
  90.  
  91. class AssociateErrorTestCase(unittest.TestCase):
  92.     def setUp(self):
  93.         self.filename = self.__class__.__name__ + '.db'
  94.         homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
  95.         self.homeDir = homeDir
  96.         try:
  97.             os.mkdir(homeDir)
  98.         except os.error:
  99.             import glob
  100.             files = glob.glob(os.path.join(self.homeDir, '*'))
  101.             for file in files:
  102.                 os.remove(file)
  103.         self.env = db.DBEnv()
  104.         self.env.open(homeDir, db.DB_CREATE | db.DB_INIT_MPOOL)
  105.  
  106.     def tearDown(self):
  107.         self.env.close()
  108.         self.env = None
  109.         import glob
  110.         files = glob.glob(os.path.join(self.homeDir, '*'))
  111.         for file in files:
  112.             os.remove(file)
  113.  
  114.  
  115.     def test00_associateDBError(self):
  116.         if verbose:
  117.             print '\n', '-=' * 30
  118.             print "Running %s.test00_associateDBError..." % \
  119.                   self.__class__.__name__
  120.  
  121.         dupDB = db.DB(self.env)
  122.         dupDB.set_flags(db.DB_DUP)
  123.         dupDB.open(self.filename, "primary", db.DB_BTREE, db.DB_CREATE)
  124.  
  125.         secDB = db.DB(self.env)
  126.         secDB.open(self.filename, "secondary", db.DB_BTREE, db.DB_CREATE)
  127.  
  128.         # dupDB has been configured to allow duplicates, it can't
  129.         # associate with a secondary.  BerkeleyDB will return an error.
  130.         try:
  131.             def f(a,b): return a+b
  132.             dupDB.associate(secDB, f)
  133.         except db.DBError:
  134.             # good
  135.             secDB.close()
  136.             dupDB.close()
  137.         else:
  138.             secDB.close()
  139.             dupDB.close()
  140.             self.fail("DBError exception was expected")
  141.  
  142.  
  143.  
  144. #----------------------------------------------------------------------
  145.  
  146.  
  147. class AssociateTestCase(unittest.TestCase):
  148.     keytype = ''
  149.     envFlags = 0
  150.     dbFlags = 0
  151.  
  152.     def setUp(self):
  153.         self.filename = self.__class__.__name__ + '.db'
  154.         homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
  155.         self.homeDir = homeDir
  156.         try:
  157.             os.mkdir(homeDir)
  158.         except os.error:
  159.             import glob
  160.             files = glob.glob(os.path.join(self.homeDir, '*'))
  161.             for file in files:
  162.                 os.remove(file)
  163.         self.env = db.DBEnv()
  164.         self.env.open(homeDir, db.DB_CREATE | db.DB_INIT_MPOOL |
  165.                                db.DB_INIT_LOCK | db.DB_THREAD | self.envFlags)
  166.  
  167.     def tearDown(self):
  168.         self.closeDB()
  169.         self.env.close()
  170.         self.env = None
  171.         import glob
  172.         files = glob.glob(os.path.join(self.homeDir, '*'))
  173.         for file in files:
  174.             os.remove(file)
  175.  
  176.     def addDataToDB(self, d, txn=None):
  177.         for key, value in musicdata.items():
  178.             if type(self.keytype) == type(''):
  179.                 key = "%02d" % key
  180.             d.put(key, string.join(value, '|'), txn=txn)
  181.  
  182.     def createDB(self, txn=None):
  183.         self.cur = None
  184.         self.secDB = None
  185.         self.primary = db.DB(self.env)
  186.         self.primary.set_get_returns_none(2)
  187.         if db.version() >= (4, 1):
  188.             self.primary.open(self.filename, "primary", self.dbtype,
  189.                           db.DB_CREATE | db.DB_THREAD | self.dbFlags, txn=txn)
  190.         else:
  191.             self.primary.open(self.filename, "primary", self.dbtype,
  192.                           db.DB_CREATE | db.DB_THREAD | self.dbFlags)
  193.  
  194.     def closeDB(self):
  195.         if self.cur:
  196.             self.cur.close()
  197.             self.cur = None
  198.         if self.secDB:
  199.             self.secDB.close()
  200.             self.secDB = None
  201.         self.primary.close()
  202.         self.primary = None
  203.  
  204.     def getDB(self):
  205.         return self.primary
  206.  
  207.  
  208.     def test01_associateWithDB(self):
  209.         if verbose:
  210.             print '\n', '-=' * 30
  211.             print "Running %s.test01_associateWithDB..." % \
  212.                   self.__class__.__name__
  213.  
  214.         self.createDB()
  215.  
  216.         self.secDB = db.DB(self.env)
  217.         self.secDB.set_flags(db.DB_DUP)
  218.         self.secDB.set_get_returns_none(2)
  219.         self.secDB.open(self.filename, "secondary", db.DB_BTREE,
  220.                    db.DB_CREATE | db.DB_THREAD | self.dbFlags)
  221.         self.getDB().associate(self.secDB, self.getGenre)
  222.  
  223.         self.addDataToDB(self.getDB())
  224.  
  225.         self.finish_test(self.secDB)
  226.  
  227.  
  228.     def test02_associateAfterDB(self):
  229.         if verbose:
  230.             print '\n', '-=' * 30
  231.             print "Running %s.test02_associateAfterDB..." % \
  232.                   self.__class__.__name__
  233.  
  234.         self.createDB()
  235.         self.addDataToDB(self.getDB())
  236.  
  237.         self.secDB = db.DB(self.env)
  238.         self.secDB.set_flags(db.DB_DUP)
  239.         self.secDB.open(self.filename, "secondary", db.DB_BTREE,
  240.                    db.DB_CREATE | db.DB_THREAD | self.dbFlags)
  241.  
  242.         # adding the DB_CREATE flag will cause it to index existing records
  243.         self.getDB().associate(self.secDB, self.getGenre, db.DB_CREATE)
  244.  
  245.         self.finish_test(self.secDB)
  246.  
  247.  
  248.     def finish_test(self, secDB, txn=None):
  249.         # 'Blues' should not be in the secondary database
  250.         vals = secDB.pget('Blues', txn=txn)
  251.         assert vals == None, vals
  252.  
  253.         vals = secDB.pget('Unknown', txn=txn)
  254.         assert vals[0] == 99 or vals[0] == '99', vals
  255.         vals[1].index('Unknown')
  256.         vals[1].index('Unnamed')
  257.         vals[1].index('unknown')
  258.  
  259.         if verbose:
  260.             print "Primary key traversal:"
  261.         self.cur = self.getDB().cursor(txn)
  262.         count = 0
  263.         rec = self.cur.first()
  264.         while rec is not None:
  265.             if type(self.keytype) == type(''):
  266.                 assert string.atoi(rec[0])  # for primary db, key is a number
  267.             else:
  268.                 assert rec[0] and type(rec[0]) == type(0)
  269.             count = count + 1
  270.             if verbose:
  271.                 print rec
  272.             rec = self.cur.next()
  273.         assert count == len(musicdata) # all items accounted for
  274.  
  275.  
  276.         if verbose:
  277.             print "Secondary key traversal:"
  278.         self.cur = secDB.cursor(txn)
  279.         count = 0
  280.  
  281.         # test cursor pget
  282.         vals = self.cur.pget('Unknown', flags=db.DB_LAST)
  283.         assert vals[1] == 99 or vals[1] == '99', vals
  284.         assert vals[0] == 'Unknown'
  285.         vals[2].index('Unknown')
  286.         vals[2].index('Unnamed')
  287.         vals[2].index('unknown')
  288.  
  289.         vals = self.cur.pget('Unknown', data='wrong value', flags=db.DB_GET_BOTH)
  290.         assert vals == None, vals
  291.  
  292.         rec = self.cur.first()
  293.         assert rec[0] == "Jazz"
  294.         while rec is not None:
  295.             count = count + 1
  296.             if verbose:
  297.                 print rec
  298.             rec = self.cur.next()
  299.         # all items accounted for EXCEPT for 1 with "Blues" genre
  300.         assert count == len(musicdata)-1
  301.  
  302.         self.cur = None
  303.  
  304.     def getGenre(self, priKey, priData):
  305.         assert type(priData) == type("")
  306.         if verbose:
  307.             print 'getGenre key: %r data: %r' % (priKey, priData)
  308.         genre = string.split(priData, '|')[2]
  309.         if genre == 'Blues':
  310.             return db.DB_DONOTINDEX
  311.         else:
  312.             return genre
  313.  
  314.  
  315. #----------------------------------------------------------------------
  316.  
  317.  
  318. class AssociateHashTestCase(AssociateTestCase):
  319.     dbtype = db.DB_HASH
  320.  
  321. class AssociateBTreeTestCase(AssociateTestCase):
  322.     dbtype = db.DB_BTREE
  323.  
  324. class AssociateRecnoTestCase(AssociateTestCase):
  325.     dbtype = db.DB_RECNO
  326.     keytype = 0
  327.  
  328. #----------------------------------------------------------------------
  329.  
  330. class AssociateBTreeTxnTestCase(AssociateBTreeTestCase):
  331.     envFlags = db.DB_INIT_TXN
  332.     dbFlags = 0
  333.  
  334.     def txn_finish_test(self, sDB, txn):
  335.         try:
  336.             self.finish_test(sDB, txn=txn)
  337.         finally:
  338.             if self.cur:
  339.                 self.cur.close()
  340.                 self.cur = None
  341.             if txn:
  342.                 txn.commit()
  343.  
  344.     def test13_associate_in_transaction(self):
  345.         if verbose:
  346.             print '\n', '-=' * 30
  347.             print "Running %s.test13_associateAutoCommit..." % \
  348.                   self.__class__.__name__
  349.  
  350.         txn = self.env.txn_begin()
  351.         try:
  352.             self.createDB(txn=txn)
  353.  
  354.             self.secDB = db.DB(self.env)
  355.             self.secDB.set_flags(db.DB_DUP)
  356.             self.secDB.set_get_returns_none(2)
  357.             self.secDB.open(self.filename, "secondary", db.DB_BTREE,
  358.                        db.DB_CREATE | db.DB_THREAD, txn=txn)
  359.             if db.version() >= (4,1):
  360.                 self.getDB().associate(self.secDB, self.getGenre, txn=txn)
  361.             else:
  362.                 self.getDB().associate(self.secDB, self.getGenre)
  363.  
  364.             self.addDataToDB(self.getDB(), txn=txn)
  365.         except:
  366.             txn.abort()
  367.             raise
  368.  
  369.         self.txn_finish_test(self.secDB, txn=txn)
  370.  
  371.  
  372. #----------------------------------------------------------------------
  373.  
  374. class ShelveAssociateTestCase(AssociateTestCase):
  375.  
  376.     def createDB(self):
  377.         self.primary = dbshelve.open(self.filename,
  378.                                      dbname="primary",
  379.                                      dbenv=self.env,
  380.                                      filetype=self.dbtype)
  381.  
  382.     def addDataToDB(self, d):
  383.         for key, value in musicdata.items():
  384.             if type(self.keytype) == type(''):
  385.                 key = "%02d" % key
  386.             d.put(key, value)    # save the value as is this time
  387.  
  388.  
  389.     def getGenre(self, priKey, priData):
  390.         assert type(priData) == type(())
  391.         if verbose:
  392.             print 'getGenre key: %r data: %r' % (priKey, priData)
  393.         genre = priData[2]
  394.         if genre == 'Blues':
  395.             return db.DB_DONOTINDEX
  396.         else:
  397.             return genre
  398.  
  399.  
  400. class ShelveAssociateHashTestCase(ShelveAssociateTestCase):
  401.     dbtype = db.DB_HASH
  402.  
  403. class ShelveAssociateBTreeTestCase(ShelveAssociateTestCase):
  404.     dbtype = db.DB_BTREE
  405.  
  406. class ShelveAssociateRecnoTestCase(ShelveAssociateTestCase):
  407.     dbtype = db.DB_RECNO
  408.     keytype = 0
  409.  
  410.  
  411. #----------------------------------------------------------------------
  412.  
  413. class ThreadedAssociateTestCase(AssociateTestCase):
  414.  
  415.     def addDataToDB(self, d):
  416.         t1 = Thread(target = self.writer1,
  417.                     args = (d, ))
  418.         t2 = Thread(target = self.writer2,
  419.                     args = (d, ))
  420.  
  421.         t1.start()
  422.         t2.start()
  423.         t1.join()
  424.         t2.join()
  425.  
  426.     def writer1(self, d):
  427.         for key, value in musicdata.items():
  428.             if type(self.keytype) == type(''):
  429.                 key = "%02d" % key
  430.             d.put(key, string.join(value, '|'))
  431.  
  432.     def writer2(self, d):
  433.         for x in range(100, 600):
  434.             key = 'z%2d' % x
  435.             value = [key] * 4
  436.             d.put(key, string.join(value, '|'))
  437.  
  438.  
  439. class ThreadedAssociateHashTestCase(ShelveAssociateTestCase):
  440.     dbtype = db.DB_HASH
  441.  
  442. class ThreadedAssociateBTreeTestCase(ShelveAssociateTestCase):
  443.     dbtype = db.DB_BTREE
  444.  
  445. class ThreadedAssociateRecnoTestCase(ShelveAssociateTestCase):
  446.     dbtype = db.DB_RECNO
  447.     keytype = 0
  448.  
  449.  
  450. #----------------------------------------------------------------------
  451.  
  452. def test_suite():
  453.     suite = unittest.TestSuite()
  454.  
  455.     if db.version() >= (3, 3, 11):
  456.         suite.addTest(unittest.makeSuite(AssociateErrorTestCase))
  457.  
  458.         suite.addTest(unittest.makeSuite(AssociateHashTestCase))
  459.         suite.addTest(unittest.makeSuite(AssociateBTreeTestCase))
  460.         suite.addTest(unittest.makeSuite(AssociateRecnoTestCase))
  461.  
  462.         if db.version() >= (4, 1):
  463.             suite.addTest(unittest.makeSuite(AssociateBTreeTxnTestCase))
  464.  
  465.         suite.addTest(unittest.makeSuite(ShelveAssociateHashTestCase))
  466.         suite.addTest(unittest.makeSuite(ShelveAssociateBTreeTestCase))
  467.         suite.addTest(unittest.makeSuite(ShelveAssociateRecnoTestCase))
  468.  
  469.         if have_threads:
  470.             suite.addTest(unittest.makeSuite(ThreadedAssociateHashTestCase))
  471.             suite.addTest(unittest.makeSuite(ThreadedAssociateBTreeTestCase))
  472.             suite.addTest(unittest.makeSuite(ThreadedAssociateRecnoTestCase))
  473.  
  474.     return suite
  475.  
  476.  
  477. if __name__ == '__main__':
  478.     unittest.main(defaultTest='test_suite')
  479.